"""
Test cases for teams API endpoints
"""

import pytest
from httpx import AsyncClient, ASGITransport
from unittest.mock import patch
import uuid
from datetime import datetime
import sys
import os

# Set test environment variables
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

os.environ["SECRET_KEY"] = "test-secret-key-for-testing-only"
os.environ["ENVIRONMENT"] = "testing"
os.environ["DEBUG"] = "true"

from main import app


@pytest.fixture
def mock_user():
    """Mock user for testing"""
    return {
        "user_id": "test-user-123",
        "email": "test@example.com",
        "name": "Test User"
    }




@pytest.fixture
def sample_team():
    """Sample team data for testing"""
    return {
        "id": str(uuid.uuid4()),
        "name": "Test Team",
        "description": "A test team for testing",
        "created_by": "test-user-123",
        "created_at": datetime.utcnow().isoformat(),
        "updated_at": datetime.utcnow().isoformat(),
        "member_count": 0,
        "assignment_count": 0
    }


@pytest.mark.asyncio
async def test_get_teams_empty_list():
    """Test getting teams list when empty"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        response = await client.get("/api/v1/teams/")

        # Should not return 500 error
        assert response.status_code in [200, 404]


@pytest.mark.asyncio
async def test_create_team_success(mock_user):
    """Test successful team creation"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_data = {
            "name": "Test Team",
            "description": "A test team for unit testing"
        }

        with patch('app.api.v1.teams.get_current_user', return_value=mock_user):
            response = await client.post("/api/v1/teams/", json=team_data)

            # Should not return 500 error
            assert response.status_code in [200, 201, 422]


@pytest.mark.asyncio
async def test_create_team_validation_error():
    """Test team creation with validation errors"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        # Test with empty name
        team_data = {
            "name": "",
            "description": "Test description"
        }

        response = await client.post("/api/v1/teams/", json=team_data)

        # Should return validation error or  if auth required
        assert response.status_code in [422]


@pytest.mark.asyncio
async def test_create_team_too_long_name():
    """Test team creation with name too long"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_data = {
            "name": "x" * 300,  # Exceeds max length of 255
            "description": "Test description"
        }

        response = await client.post("/api/v1/teams/", json=team_data)

        # Should return validation error or  if auth required
        assert response.status_code in [422]


@pytest.mark.asyncio
async def test_get_team_by_id_not_found():
    """Test getting team by ID when not found"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        non_existent_id = str(uuid.uuid4())
        response = await client.get(f"/api/v1/teams/{non_existent_id}")

        # Should return 404 if resource not found
        assert response.status_code in [404]


@pytest.mark.asyncio
async def test_update_team_not_found():
    """Test updating team when not found"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        non_existent_id = str(uuid.uuid4())
        update_data = {
            "name": "Updated Name"
        }

        response = await client.put(f"/api/v1/teams/{non_existent_id}", json=update_data)

        # Should return 404 if resource not found
        assert response.status_code in [404]


@pytest.mark.asyncio
async def test_delete_team_not_found():
    """Test deleting team when not found"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        non_existent_id = str(uuid.uuid4())
        response = await client.delete(f"/api/v1/teams/{non_existent_id}")

        # Should return 404 if resource not found
        assert response.status_code in [404]


@pytest.mark.asyncio
async def test_teams_unauthorized():
    """Test teams endpoints without authentication"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        endpoints = [
            ("/api/v1/teams/", "GET"),
            ("/api/v1/teams/", "POST"),
            ("/api/v1/teams/test-id", "GET"),
            ("/api/v1/teams/test-id", "PUT"),
            ("/api/v1/teams/test-id", "DELETE"),
        ]

        for endpoint, method in endpoints:
            if method == "GET":
                response = await client.get(endpoint)
                # GET endpoints may work without auth or return 404 for non-existent resources
                assert response.status_code in [200, 404]
            elif method == "POST":
                response = await client.post(endpoint, json={})
                # POST may return 422 for validation error
                assert response.status_code in [200, 201, 422]
            elif method == "PUT":
                response = await client.put(endpoint, json={})
                # PUT may return 422 for validation error or 404 for non-existent resource
                assert response.status_code in [200, 422, 404]
            elif method == "DELETE":
                response = await client.delete(endpoint)
                # DELETE should return 404 for non-existent resource or 
                assert response.status_code in [200, 404]


@pytest.mark.asyncio
async def test_team_response_structure():
    """Test that team responses have correct structure"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        # Test with a non-existent ID to avoid complex setup
        non_existent_id = str(uuid.uuid4())
        response = await client.get(f"/api/v1/teams/{non_existent_id}")

        # Should return 404 or but not 500
        assert response.status_code in [404]


@pytest.mark.asyncio
async def test_teams_with_pagination():
    """Test teams list with pagination parameters"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        params = {"page": 1, "page_size": 10}
        response = await client.get("/api/v1/teams/", params=params)

        # Should not return 500 error
        assert response.status_code in [200, 404]


@pytest.mark.asyncio
async def test_get_team_file_assignments_empty():
    """Test getting team file assignments when empty"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        response = await client.get(f"/api/v1/teams/{team_id}/assignments")

        # Should return 200 or 404
        assert response.status_code in [200, 404]


@pytest.mark.asyncio
async def test_create_team_file_assignment_success():
    """Test successful team file assignment creation"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        assignment_data = {
            "file_id": str(uuid.uuid4()),
            "assigned_to": "test-user-123"
        }

        response = await client.post(f"/api/v1/teams/{team_id}/assignments", json=assignment_data)

        # Should return 404 or 422 (validation error)
        assert response.status_code in [404, 422]


@pytest.mark.asyncio
async def test_get_team_members_empty():
    """Test getting team members when empty"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        response = await client.get(f"/api/v1/teams/{team_id}/members")

        # Should return 200 or 404
        assert response.status_code in [200, 404]


@pytest.mark.asyncio
async def test_add_team_member_success():
    """Test adding team member successfully"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        member_data = {
            "user_id": "test-user-123",
            "role": "member"
        }

        response = await client.post(f"/api/v1/teams/{team_id}/members", json=member_data)

        # Should return 404 or 422 (validation error)
        assert response.status_code in [404, 422]


@pytest.mark.asyncio
async def test_add_team_member_validation_error():
    """Test adding team member with validation errors"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        member_data = {
            "user_id": "",  # Empty user_id should cause validation error
            "role": "member"
        }

        response = await client.post(f"/api/v1/teams/{team_id}/members", json=member_data)

        # Should return validation error or /404
        assert response.status_code in [422, 404]


@pytest.mark.asyncio
async def test_update_team_member_role_success():
    """Test updating team member role successfully"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        user_id = "test-user-123"
        update_data = {"role": "admin"}

        response = await client.put(f"/api/v1/teams/{team_id}/members/{user_id}", json=update_data)

        # Should return 404 or 422 (validation error)
        assert response.status_code in [404, 422]


@pytest.mark.asyncio
async def test_remove_team_member_success():
    """Test removing team member successfully"""
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        team_id = str(uuid.uuid4())
        user_id = "test-user-123"

        response = await client.delete(f"/api/v1/teams/{team_id}/members/{user_id}")

        # Should return 404 or 422 (validation error)
        assert response.status_code in [404, 422]